home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 January / macformat-033.iso / mac / Shareware City / Developers / ABox.v1.8 / CPlus Files / ABObject.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-23  |  14.2 KB  |  619 lines  |  [TEXT/MMCC]

  1. /*    
  2.     Copyright © 1991-1995 by TopSoft Inc.  All rights reserved.
  3.  
  4.     You may distribute this file under the terms of the TopSoft
  5.     Artistic License, accompanying this package.
  6.     
  7.     This file was developed by George (ty) Tempel in connection with TopSoft, Inc..
  8.     See the Modification History for more details.
  9.  
  10. Product
  11.     About Box
  12.  
  13. FILE
  14.     ABObject.c
  15.  
  16. NAME
  17.     ABObject.c, part of the ABox project source code,
  18.     responsible for handling the AboutBox drawn object stuff.
  19.  
  20. DESCRIPTION
  21.     This file contains defines for the about box modules.
  22.     
  23. DEVELOPED BY
  24.     George (ty) Tempel                netromancr@aol.com
  25.     All code in this file, and its associated header file was
  26.     Created by George (ty) Tempel in connection with the TopSoft, Inc.
  27.     "FilterTop" application development, except where noted.
  28.  
  29. CARETAKER - George (ty) Tempel <netromancr@aol.com>
  30.      Please consult this person for any changes or suggestions to this file.
  31.  
  32. MODIFICATION HISTORY
  33.  
  34.     dd mmm yy    -    xxx    -    patchxx: description of patch
  35.     9 June 94    -    ty    -    Initial Version Created
  36.     20-july-94    -    ty    -    initial version released
  37.     12-aug-94    -    ty    -    1.0.8 -- added mix-in class ABUEnvQD
  38.                             for handling of quickdraw features
  39.     12-jan-95    -    ty    -    1.0.10 -- changed how the frames are drawn, inspired
  40.                             by the adorners of macapp--the frame will draw around
  41.                             the rect specified, not inside the rect. Thus,
  42.                             there will be no difference when viewing in 1bit vs n-bit
  43.     10-mar-95    -    ty    -    1.2 removed utility methods from here to ABUEnvQD
  44.                                 since they were quickdraw related; inclusion of some
  45.                                 new methods for handling DeviceLoop driven 3d frames
  46.                                 of the object (pretty neat stuff!)
  47.     20-mar-95    -    ty    -    1.4 fixes to properly restore the clip region
  48.     21-mar-95    -    ty    -    1.5    fixes for ColorQD cautions on non-colorQD machines and
  49.                                 better region handling for multiple devices
  50.     23-may-95    -    ty    -    changes for compatibility with the CodeWarrior CW6
  51.                             release and the associated Universal Headers from Apple:
  52.                             most methods that returned references now have "Ref" at
  53.                             the end of their methods names to prevent possible collisions
  54.                             with datatypes and classes of the same name (older versions
  55.                             of the compiler didn't have a problem with this).
  56.  
  57. */
  58.  
  59. /*===========================================================================*/
  60.  
  61. /*======= Segmentation directives ========*/
  62.  
  63. #ifdef USE_MANUAL_SEGMENTATION
  64. #pragma segment ty
  65. #endif
  66.  
  67. /*============ Header files ==============*/
  68.     
  69. #include     "ABObject.h"
  70.  
  71. /*=============== Globals ================*/
  72.  
  73. /*================ CODE ==================*/
  74.  
  75. #ifndef topLeft
  76. #define topLeft(r) (((Point *)&(r))[0])
  77. #endif
  78.  
  79. #ifndef botRight
  80. #define botRight(r) (((Point *)&(r))[1])
  81. #endif
  82.  
  83.  
  84. /*=============================== ABObject::ABObject ================================*/
  85. ABObject::ABObject(void)
  86. {
  87.     mRefCon = 0;
  88.     mVisibleObject = false;
  89.     
  90.     mOurWindow = NULL;
  91.     
  92.     mObjectRect.top = mObjectRect.bottom = mObjectRect.right = mObjectRect.left = 0;
  93.     
  94. } // end ABObject
  95.  
  96.  
  97.  
  98. /*=============================== ABObject::~ABObject ================================*/
  99. ABObject::~ABObject(void)
  100. {
  101. } // end ~ABObject
  102.  
  103.  
  104.  
  105. /*=============================== ABObject::Draw ================================*/
  106. OSErr    ABObject::Draw(WindowPtr window)
  107. {
  108.     this->OurWindowRef() = window;
  109.  
  110.     //    begin here...
  111.     //
  112.     //    OVERRIDE THIS FUNCTION
  113.     return this->DrawFrame();
  114. } // end Draw
  115.  
  116.  
  117.  
  118. /*=============================== ABObject::Update ================================*/
  119. OSErr    ABObject::Update(WindowPtr window)
  120. {
  121.     
  122.     //    begin here...
  123.     //
  124.     //    OVERRIDE THIS FUNCTION
  125.     
  126.     return this->Draw(window);
  127.     
  128. } // end Update
  129.  
  130.  
  131.  
  132.  
  133. /*=============================== ABObject::Event ================================*/
  134. Boolean    ABObject::Event(EventRecord* /*eventRec*/)
  135. {
  136. //#pragma unused (eventRec)
  137.     
  138.     //    begin here...
  139.     //
  140.     //    OVERRIDE THIS FUNCTION
  141.     
  142.     return false;
  143.     
  144. } // end Event
  145.  
  146.  
  147.  
  148. /*=============================== ABObject::Stop ================================*/
  149. OSErr    ABObject::Stop(void)
  150. {
  151.     
  152.     //    begin here...
  153.     //
  154.     //    OVERRIDE THIS FUNCTION
  155.     
  156.     return noErr;
  157. } // end Stop
  158.  
  159.  
  160.  
  161.  
  162. /*=============================== ABObject::CheckFile ================================*/
  163. Boolean    ABObject::CheckFile(FSSpecPtr /*fssptr*/)
  164. {
  165. //#pragma    unused (fssptr)
  166.  
  167.     //    begin here...
  168.     //
  169.     //    OVERRIDE THIS FUNCTION
  170.     
  171.     return false;
  172. } // end CheckFile
  173.  
  174.  
  175.  
  176. /*=============================== ABObject::InitializeObject ================================*/
  177. OSErr    ABObject::InitializeObject(void)
  178. {
  179.     //    begin here...
  180.     //
  181.     //    OVERRIDE THIS FUNCTION
  182.     
  183.     return noErr;
  184. } // end InitializeObject
  185.  
  186.  
  187.  
  188. /*=============================== ABObject::Resize ================================*/
  189. OSErr    ABObject::Resize(Rect const* /*field*/)
  190. {
  191. //#pragma    unused (field)
  192.     
  193.     //    begin here...
  194.     //
  195.     //    OVERRIDE THIS FUNCTION
  196.     
  197.     return noErr;
  198. } // end Resize
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205. /*=============================== ABObject::GetProperty ================================*/
  206. OSErr    ABObject::GetProperty(ABProperty prop, 
  207.                                 void *ptr, 
  208.                                 long *ptrSize)
  209. {
  210.     OSErr    error = noErr;
  211.     long    pSize;
  212.     
  213.     //    begin here...
  214.     
  215.     if (!ptr)
  216.         return kABPropertyNullStorage;
  217.     
  218.     switch (prop)
  219.     {
  220.         case    kABObjectRefCon:
  221.                     *((long *)ptr) = mRefCon;
  222.                     pSize = kABObjectRefConSize;
  223.                     break;
  224.         case    kABObjectVisible:
  225.                     *((Boolean *)ptr) = this->VisibleObject();
  226.                     pSize = kABObjectVisibleSize;
  227.                     break;
  228.         case    kABObjectRect:
  229.                     (*(Rect *)ptr) = this->ObjectRect();
  230.                     pSize = kABObjectRectSize;
  231.                     break;
  232.         default:
  233.                     error = kABObjectSuperProperty::GetProperty (prop, ptr, ptrSize);
  234.                     break;
  235.     } // end switch block
  236.     
  237.     if (ptrSize && !error)
  238.         *ptrSize = pSize;
  239.     return error;
  240.     
  241. } // end GetProperty
  242.  
  243.  
  244.  
  245. /*=============================== ABObject::SetProperty ================================*/
  246. OSErr    ABObject::SetProperty(ABProperty prop, 
  247.                                 void *ptr, 
  248.                                 long ptrSize)
  249. {
  250.     OSErr    error = noErr;
  251.     
  252.     //    begin here...
  253.     
  254.     if (!ptr)
  255.         return kABPropertyNullStorage;
  256.     
  257.     switch (prop)
  258.     {
  259.         case    kABObjectRefCon:
  260.                     mRefCon = *((long *)ptr);
  261.                     break;
  262.         case    kABObjectVisible:
  263.                     this->VisibleObject() = *((Boolean *)ptr);
  264.                     break;
  265.         case    kABObjectRect:
  266.                     this->ObjectRect() = (*(Rect *)ptr);
  267.                     //::InsetRect(&this->ObjectRect(), 1, 1);
  268.                     break;
  269.         default:
  270.                     error = kABObjectSuperProperty::SetProperty (prop, ptr, ptrSize);
  271.                     break;
  272.     } // end switch block
  273.     
  274.     return error;
  275.     
  276. } // end SetProperty
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283. /*=============================== ABObject::ScaleRectToFit ================================*/
  284. //
  285. //    ScaleRectToFit will scale a rectangle to fit wholly within another, with an
  286. //    optional reduction factor (expressed as 0.75 for a reduction to 75%, or 1.0
  287. //    for normal).
  288. //
  289. //    The function returns a pointer to the newly scaled rectangle in the parameter list,
  290. //    and returns an OSErr for error processing.
  291. //
  292. //OSErr    ABObject::ScaleRectToFit(Rect& item, Rect const *area, float factor)
  293. OSErr    ABObject::ScaleRectToFit(Rect& item, const Rect& area, float factor)
  294. {
  295.     OSErr    error = noErr;
  296.  
  297.     float    scale,
  298.             xratio,
  299.             yratio,
  300.             extra = factor;
  301.     
  302.     short    rectWidth,
  303.             rectHeight,
  304.             areaWidth,
  305.             areaHeight;
  306.     
  307.     
  308.     //    begin...
  309.     
  310.     //    begin here...
  311.     //
  312.     rectWidth = item.right - item.left;
  313.     rectHeight = item.bottom - item.top;
  314.     
  315.     areaWidth = area.right - area.left;
  316.     areaHeight = area.bottom - area.top;
  317.  
  318.     if ((rectWidth <= areaWidth) && (rectHeight <= areaHeight)) 
  319.     {
  320.         //    the rect fits already...
  321.         //
  322.     } else {
  323.         xratio = (float)(areaWidth * extra) / (float)rectWidth;
  324.         yratio = (float)(areaHeight * extra) / (float)rectHeight;
  325.         
  326.         scale = (xratio < yratio) ? xratio : yratio;
  327.         
  328.         item.right = item.left + rectWidth * scale;
  329.         item.bottom = item.top + rectHeight * scale;
  330.         
  331.     }    //    end if else block...    
  332.     
  333.     return error;
  334.     
  335. }    //    end of function ScaleRectToFit()
  336.  
  337.  
  338.  
  339. /*=============================== ABObject::CanDraw3dBezel ==================================*/
  340. //
  341. //    returns true if the pixel depth is sufficient for the bezel effect
  342. //
  343. Boolean
  344. ABObject::CanDraw3dBezel(short inDepth)
  345. {
  346.     return inDepth >= kABminPixelDepthForBezel;
  347. }
  348.  
  349.  
  350.  
  351.  
  352.  
  353. /*=============================== ABObject::EraseFrame ===============================*/
  354. //
  355. //    this function will erase the beveled frame from around a rect area
  356. //
  357. //    it will return an OSErr type to indicate error conditions.
  358. //
  359. //
  360. //    is called by:
  361. //
  362. OSErr
  363. ABObject::EraseFrame (void) const
  364. {
  365.     return this->EraseFrame(this->ObjectRect());
  366. }    //    end of function EraseFrame()
  367.  
  368.  
  369.  
  370.  
  371.  
  372. /*=============================== ABObject::EraseFrame ===============================*/
  373. //
  374. //    this function will erase the beveled frame from around a rect area
  375. //
  376. //    it will return an OSErr type to indicate error conditions.
  377. //
  378. //
  379. //    is called by:
  380. //
  381. OSErr    
  382. ABObject::EraseFrame (Rect& rect)
  383. {
  384.     OSErr    error = noErr;
  385.     
  386.     //    begin here...
  387.     
  388.     Rect theRect = rect;
  389.     
  390.     if (::EmptyRect(&theRect))
  391.         return noErr;
  392.     
  393.     ::InsetRect (&theRect, -kABbezelWidth, -kABbezelWidth);
  394.     theRect.right += 1;
  395.     theRect.bottom += 1;
  396.     ::EraseRect (&theRect);
  397.     theRect.right -= 1;
  398.     theRect.bottom -= 1;
  399.     ::InsetRect (&theRect, kABbezelWidth, kABbezelWidth);
  400.  
  401.     return (error);
  402.     
  403. }    //    end of function EraseFrame()
  404.  
  405.  
  406.  
  407.  
  408.  
  409. /*=============================== ABObject::DrawFrame ===============================*/
  410. //
  411. //    this function will draw a beveled frame around a rect area
  412. //
  413. OSErr
  414. ABObject::DrawFrame (void) const
  415. {
  416.     return this->DrawFrame(this->ObjectRect());
  417. }
  418.  
  419.  
  420.  
  421. /*=============================== ABObject::DrawFrame ===============================*/
  422. //
  423. //    this function will draw a beveled frame around a rect area
  424. //
  425. //    The function returns an OSErr to indicate error conditions.
  426. //
  427. OSErr    
  428. ABObject::DrawFrame (Rect& inRect)
  429. {
  430.     OSErr anError = noErr;
  431.     
  432.     //    draw the frame via device loop calls...better in the long run if we can do this!
  433.     
  434.     RgnHandle theDrawRegion = ::NewRgn();
  435.     DeviceLoopDrawingUPP theDrawUPP = NewDeviceLoopDrawingProc(ABObject::DeviceLoopDrawFrame);
  436.     Rect theRect = inRect;
  437.     
  438.     if (theDrawUPP && theDrawRegion)
  439.     {
  440.         //    construct a region from the given rect...
  441.         ::RectRgn (theDrawRegion, &theRect);
  442.         
  443.         //    now invoke the toolbox DeviceLoop
  444.         ::DeviceLoop (theDrawRegion, 
  445.                         theDrawUPP, 
  446.                         (long)&theRect, 
  447.                         allDevices);
  448.     } else {
  449.         //    there was a problem, so try and draw the region best we can...
  450.         ABUEnvQD hasColorQD;
  451.         ABObject::DeviceLoopDrawFrame ((hasColorQD.HasColorQD() ? ABUEnvQD::GetPixelDepth(::GetGDevice()) : 1),
  452.                                         allDevices,
  453.                                         NULL,
  454.                                         (long)&theRect);
  455.         
  456.     }
  457.     
  458.     if (theDrawRegion)
  459.     {
  460.         ::DisposeRgn(theDrawRegion);
  461.         theDrawRegion = NULL;
  462.     }
  463.     
  464.     if (theDrawUPP)
  465.     {
  466.         DisposeRoutineDescriptor(theDrawUPP);
  467.         theDrawUPP = NULL;
  468.     }
  469.         
  470.     return anError;
  471.     
  472. }
  473.  
  474.  
  475. /*=============================== ABObject::DeviceLoopDrawFrame ===============================*/
  476. //
  477. //    this function will draw a beveled frame around a rect area
  478. //    following the suggestions put forth in Develop #15 for 3d effects 
  479. //    in user interfaces.
  480. //
  481. //    It is _this_ method that does the actual frame drawing...all other DrawFrame
  482. //    method eventually lead here via DeviceLoop...
  483. //
  484. pascal void    
  485. ABObject::DeviceLoopDrawFrame (short inDepth, short inDeviceFlags, GDHandle inDevice, long inUserData)
  486. {
  487.     OSErr            error = noErr;
  488.     
  489.     Rect userAreaToDraw = *((Rect*)inUserData);
  490.     RGBColor    frameColor, prevColor;
  491.     
  492.     //    begin here...
  493.     
  494.     if (::EmptyRect(&userAreaToDraw))
  495.         return;
  496.     
  497.     //    1.1--expand the rect area so we can draw stuff
  498.     ::InsetRect (&userAreaToDraw, -kABbezelWidth, -kABbezelWidth);
  499.     Rect drawableIntersection = userAreaToDraw;
  500.  
  501.     //    now determine if we should even bother drawing here just as yet...
  502.     RgnHandle theClipRegion = ::NewRgn();
  503.     if (theClipRegion)
  504.         ::GetClip(theClipRegion);
  505.         
  506.     RgnHandle theDrawRegion = ::NewRgn();
  507.     
  508.     ABUEnvQD hasColorQD;
  509.     
  510.     Rect deviceBounds;
  511.     Rect globalAreaToDraw = drawableIntersection;
  512.  
  513.     ::SetRect(&deviceBounds, 0, 0, 0, 0);
  514.     if (inDevice)
  515.     {
  516.         deviceBounds = (*inDevice)->gdRect;
  517.     } else {
  518.         if (hasColorQD.HasColorQD())
  519.         {
  520.             GDHandle device = ::GetGDevice();
  521.             if (device)
  522.                 deviceBounds = (*device)->gdRect;
  523.         }
  524.     }
  525.         
  526.     ::LocalToGlobal(&topLeft(globalAreaToDraw));
  527.     ::LocalToGlobal(&botRight(globalAreaToDraw));
  528.     
  529.     if (::SectRect(&deviceBounds, &globalAreaToDraw, &drawableIntersection))
  530.     {
  531.         //    there is an intersection, so set things up...
  532.         if (theDrawRegion && theClipRegion)
  533.         {
  534.             //    convert back to local coords...
  535.             ::GlobalToLocal(&topLeft(drawableIntersection));
  536.             ::GlobalToLocal(&botRight(drawableIntersection));
  537.             
  538.             //    start setting up the drawing regions and clip regions now...
  539.             ::RectRgn (theDrawRegion, &drawableIntersection);
  540.             
  541.             //    set theDrawRegion to be the clipped area, just to
  542.             //    be nice
  543.  
  544.             if (::EmptyRgn(theClipRegion) == false)
  545.                 ::SectRgn(theDrawRegion, theClipRegion, theDrawRegion);
  546.             
  547.             //    now clip to the visRgn too...
  548.             ::SectRgn(theDrawRegion, qd.thePort->visRgn, theDrawRegion);
  549.             
  550.             //    now set the _new_ clip region...
  551.             ::SetClip (theDrawRegion);
  552.         }
  553.     }
  554.     
  555.     //    see if there really was an intersection to draw into...
  556.     if (theDrawRegion && theClipRegion && (::EmptyRgn(theDrawRegion) == false))
  557.     {
  558.         //    we should always get here, but just to make certain...
  559.         
  560.         if (ABObject::CanDraw3dBezel(inDepth) && inDevice && hasColorQD.HasColorQD())
  561.         {
  562.             //    when called on a system without ColorQuickdraw, the inDevice parameter is
  563.             //    set to NULL...
  564.     
  565.             //    now do the draw...
  566.             ::GetForeColor (&prevColor);
  567.             
  568.             //    draw the left & top first...
  569.             //    set the color
  570.     
  571.             frameColor.blue = frameColor.red = frameColor.green = k3D_lineMedLightGrey;
  572.             if (hasColorQD.HasColorQD())
  573.                 ::RGBForeColor (&frameColor);    
  574.             
  575.             ::MoveTo (userAreaToDraw.left, userAreaToDraw.bottom);
  576.             ::LineTo (userAreaToDraw.left, userAreaToDraw.top);
  577.             ::LineTo (userAreaToDraw.right, userAreaToDraw.top);
  578.  
  579.             //    draw the bottom and right...
  580.             //    set the bottom/right colors        
  581.             frameColor.blue = frameColor.red = frameColor.green = k3D_lineWhite;
  582.             if (hasColorQD.HasColorQD())
  583.                 ::RGBForeColor (&frameColor);    
  584.             
  585.             ::InsetRgn (theDrawRegion, -kABbezelWidth, -kABbezelWidth);
  586.             ::SetClip (theDrawRegion);
  587.             ::MoveTo (userAreaToDraw.left, userAreaToDraw.bottom);
  588.             ::LineTo (userAreaToDraw.right, userAreaToDraw.bottom);
  589.             ::LineTo (userAreaToDraw.right, userAreaToDraw.top);
  590.         
  591.             if (hasColorQD.HasColorQD())
  592.                 ::RGBForeColor(&prevColor);
  593.         
  594.         } else {
  595.             ::FrameRect (&userAreaToDraw);
  596.         
  597.         }    //    end if else block...
  598.     
  599.     }
  600.     
  601.     if (theClipRegion)
  602.     {
  603.         //    restore the clip region
  604.         ::SetClip (theClipRegion);
  605.         ::DisposeRgn(theClipRegion);
  606.         theClipRegion = NULL;
  607.     }
  608.     
  609.     if (theDrawRegion)
  610.     {
  611.         ::DisposeRgn(theDrawRegion);
  612.         theDrawRegion = NULL;
  613.     }
  614.     
  615.     return;
  616.     
  617. }    // end of function DrawFrame()
  618.  
  619.